/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.animation.bitmap.wrapper;

import com.facebook.common.logging.FLog;
import com.facebook.common.references.CloseableReference;
import com.facebook.fresco.animation.bitmap.BitmapFrameCache;
import com.facebook.fresco.animation.bitmap.BitmapFrameRenderer;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend;
import com.facebook.imagepipeline.animated.impl.AnimatedImageCompositor;
import com.facebook.imagepipeline.annotation.Nullable;
import com.oszc.bbhmlibrary.utils.LogUtil;
import ohos.agp.utils.RectFloat;
import ohos.media.image.PixelMap;

/**
 * {@link BitmapFrameRenderer} that wraps around an {@link AnimatedDrawableBackend}.
 */
public class AnimatedDrawableBackendFrameRenderer implements BitmapFrameRenderer {

    private static final Class<?> TAG = AnimatedDrawableBackendFrameRenderer.class;

    private final BitmapFrameCache mBitmapFrameCache;

    private AnimatedDrawableBackend mAnimatedDrawableBackend;
    private AnimatedImageCompositor mAnimatedImageCompositor;

    private final AnimatedImageCompositor.Callback mCallback =
            new AnimatedImageCompositor.Callback() {
                @Override
                public void onIntermediateResult(int frameNumber, PixelMap bitmap) {
                    // We currently don't cache intermediate bitmaps here
                }

                @Nullable
                @Override
                public CloseableReference<PixelMap> getCachedBitmap(int frameNumber) {
                    return mBitmapFrameCache.getCachedFrame(frameNumber);
                }
            };

    public AnimatedDrawableBackendFrameRenderer(
            BitmapFrameCache bitmapFrameCache, AnimatedDrawableBackend animatedDrawableBackend) {
        mBitmapFrameCache = bitmapFrameCache;
        mAnimatedDrawableBackend = animatedDrawableBackend;

        mAnimatedImageCompositor = new AnimatedImageCompositor(mAnimatedDrawableBackend, mCallback);
    }

    @Override
    public void setBounds(@Nullable RectFloat bounds) {
        AnimatedDrawableBackend newBackend = mAnimatedDrawableBackend.forNewBounds(bounds);
        if (newBackend != mAnimatedDrawableBackend) {
            mAnimatedDrawableBackend = newBackend;
            mAnimatedImageCompositor = new AnimatedImageCompositor(mAnimatedDrawableBackend, mCallback);
        }
    }

    @Override
    public int getIntrinsicWidth() {
        return mAnimatedDrawableBackend.getWidth();
    }

    @Override
    public int getIntrinsicHeight() {
        return mAnimatedDrawableBackend.getHeight();
    }

    @Override
    public boolean renderFrame(int frameNumber, PixelMap targetBitmap) {
        try {
            LogUtil.error(TAG.getSimpleName(),"canvas renderFrame frameNumber:"+frameNumber+"   bitmap:"+targetBitmap);
            mAnimatedImageCompositor.renderFrame(frameNumber, targetBitmap);
        } catch (IllegalStateException exception) {
            LogUtil.error(TAG.getSimpleName(),String .format("Rendering of frame unsuccessful. Frame number: %d   exception:%s", frameNumber,exception.getMessage()));
            FLog.e(TAG, exception, "Rendering of frame unsuccessful. Frame number: %d", frameNumber);
            return false;
        }
        return true;
    }
}
